package com.zx.factory;

import com.zx.annotations.Autowired;
import com.zx.annotations.Service;
import com.zx.annotations.Transactional;
import com.zx.tx.TransactionManager;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @ProjectName: iocaop
 * @Package: com.zx.factory
 * @ClassName: InitBeanFactory
 * @Author: 1
 * @Description: 1
 * @Date: 2021/9/16 9:23
 */
public class RegisterBean {

    private final   Map<String,Object> objMap = new HashMap<>();  // 存储对象
    private final   Map<String,Class<?>> classMap = new HashMap<>();  // 存储对象
    private   ProxyFactory proxyFactory;
    private List<BeanDefinition> beanDefinitionList;

    public RegisterBean(List<BeanDefinition> beanDefinitionList){
          proxyFactory = new ProxyFactory();
          proxyFactory.setTransactionManager(new TransactionManager());
         this.beanDefinitionList =beanDefinitionList;
    }


    public    void registerObj ()  {
        try {
        for (BeanDefinition beanDefinition:beanDefinitionList
             ) {
            //id
            Service service = beanDefinition.getService();
            String beanId =service.value();
            if(beanId == null || "".equals(beanId)){
                beanId = toLowerCaseFirstOne(beanDefinition.getClassName());
            }
            //实例化
             Object o = beanDefinition.getConstructor().newInstance();

            //判断是否需要管理事务
            Transactional transactional = beanDefinition.getTransactional();
            if(transactional !=null){
                //判断是否有实现类
                if(beanDefinition.getInterfaces().length >0){
                    //使用jdk代理
                      o =  proxyFactory.getJdkProxy(o);
                }else{
                    //使用Cglib代理
                      o =  proxyFactory.getCglibProxy(o);
                }
            }
            objMap.put(beanId,o);
            classMap.put(beanId,beanDefinition.getaClass());
        }

            // 判断是否需要属性注入
            injectionProperties();

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 依赖注入
     */
    private  void injectionProperties() throws IllegalAccessException {
        Set<String> strings = objMap.keySet();
        for (String s :strings
             ) {
            Object o = objMap.get(s);
            Class aClass = classMap.get(s);
            Field[] declaredFields = aClass.getDeclaredFields();
            for (Field field :declaredFields
            ) {
                Autowired annotation = field.getAnnotation(Autowired.class);
                if(annotation == null)continue;
                //获取注入对象
                Object bean =  objMap.get(field.getName());
                if(bean !=null){
                    // 私有访问允许访问
                    field.setAccessible(true);
                    // 给属性赋值
                    field.set(o, bean);
                }
            }
        }
    }


    // 首字母转小写
    public   String toLowerCaseFirstOne(String s) {
        if (Character.isLowerCase(s.charAt(0)))
            return s;
        else
            return (new StringBuilder()).append(Character.toLowerCase(s.charAt(0))).append(s.substring(1)).toString();
    }




    public Map<String, Object> getCacheMap() {
        return objMap;
    }
}
